import {InnKeeper, Magician, Monster, Wanderer} from "../../questGem/html/npc.mjs"

class Tile {
    constructor(aTerrain, isVisited = false, npc) {
        this.terrain = aTerrain
        this.isVisited = isVisited
        this.items = []
        this.npc = npc
    }
}

function createScreenContainer() {
    const div = document.createElement('div')
    // div.classList.add('screen')  // ??
    div.id = 'chessboard'
    return div
}

function randomPosition(dim, prng) {
    const x = Math.floor(prng() * dim.width)
    const y = Math.floor(prng() * dim.height)
    return {x, y} // NOTE: object property shorthand, same as writing { x: x, y: y}
}

function styleTileBasedOn(playerPos, tilePos, diamondPos, tile) {
    if (playerPos.x === tilePos.x && playerPos.y === tilePos.y) {
        return ['player']
    }
    // Remove the comments on the next three lines to show the diamond in the map
    // if (diamondPos.x === tilePos.x && diamondPos.y === tilePos.y) {
    //    return ['diamond']
    // }
    // if (!tile.isVisited)
    //     return [tile.terrain, 'cloaked']

    return [tile.terrain]
}

function randomChoice(arr, prng) {
    return arr[Math.floor(prng() * arr.length)]
}

function* tileGenerator(prng = Math.random) {
    const terrains = ['desert', 'forest', 'mountain', 'swamp']
    while (true) {
        const terrain = randomChoice(terrains, prng)
        yield new Tile(terrain, false, getNpcForTile(terrain, prng))
    }
}

function getNpcForTile(terrain, prng) {
    // Let's roll the dice
    const diceRoll = prng()
    // and make it 25% chance that the player will
    // meet a npc on the tile

    // if random number higher than .25 we
    if (diceRoll > .25)
        return undefined

    // let's roll the dice again, to decide
    // if the npc should be a monster (60%)
    // or friend (15%)
    // or a magician (25)
    const secondRoll = prng()

    if (secondRoll < .15)
        return new Wanderer()

    if (secondRoll < .25)
        return new Magician(prng)

    if (secondRoll < .45)
        return new InnKeeper(prng)

    // the for the rest, let's generate a monster
    switch (terrain) {
        case 'forest':
            return new Monster('bird', 5, 10, prng)
        case 'mountain':
            return new Monster('dragon', 40, 60, prng)
        case 'desert':
            return new Monster('snake', 1, 25, prng)
        case 'swamp':
            return new Monster('crocodile', 25, 35, prng)
        default:
            return undefined
    }
}

class GameMap {
    constructor(dimensions, tileiterator = tileGenerator()) {
        this.dimensions = dimensions
        const width = dimensions.width
        const height = dimensions.height
        this.tiles = new Array(height)
        this.changeList = []
        for (let x = 0; x < height; x++) {
            this.tiles[x] = new Array(width)
            for (let y = 0; y < width; y++) {
                this.tiles[x][y] = tileiterator.next().value
            }
        }
    }
}

let root = document.getElementById('gameView')
root.replaceChildren()
let container = createScreenContainer() // the game map container
root.appendChild(container)

let gameMap = new GameMap({width: 15, height: 15})
gameMap.playerPos = {
    x: Math.floor(gameMap.dimensions.width / 2),
    y: Math.floor(gameMap.dimensions.height / 2)
}
let gemPos = randomPosition(gameMap.dimensions, Math.random)

for (let i = 0; i < gameMap.tiles.length; i++) {
    for (let j = 0; j < gameMap.tiles[i].length; j++) {
        var cellDiv = document.createElement('div')
        cellDiv.classList.add('cell')
        const styleClasses = styleTileBasedOn(gameMap.playerPos, {x: j, y: i}, gemPos, gameMap.tiles[i][j])
        styleClasses.forEach((styleClass) => cellDiv.classList.add(styleClass))
        container.appendChild(cellDiv)
    }
}
